/**
* Copyright 2014 Jörg Prante
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xbib.logging.log4j2;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.nosql.appender.NoSqlProvider;
import org.apache.logging.log4j.status.StatusLogger;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
@Plugin(name = "Elasticsearch", category = "Core", printObject = true)
public class ElasticsearchProvider implements NoSqlProvider<ElasticsearchConnection> {
private static final Logger logger = StatusLogger.getLogger();
private final ElasticsearchTransportClient client;
private final String description;
private ElasticsearchProvider(final ElasticsearchTransportClient client, final String description) {
this.client = client;
this.description = "elasticsearch{ " + description + " }";
}
@Override
public ElasticsearchConnection getConnection() {
//TODO validate client is viable
return new ElasticsearchConnection(client);
}
@Override
public String toString() {
return description;
}
/**
* Factory method for creating an Elasticsearch provider within the plugin manager.
*
* @param cluster The name of the Elasticsearch cluster to which log event documents will be written.
* @param host The host name an Elasticsearch server node of the cluster, defaults to localhost.
* @param port The port that Elasticsearch is listening on, defaults to 9300
* @param index The index that Elasticsearch shall use for indexing
* @param type The type of the index Elasticsearch shall use for indexing
* @return a new Elasticsearch provider
*/
@PluginFactory
public static ElasticsearchProvider createNoSqlProvider(
@PluginAttribute("cluster") String cluster,
@PluginAttribute("host") String host,
@PluginAttribute("port") Integer port,
@PluginAttribute("index") String index,
@PluginAttribute("type") String type,
@PluginAttribute("timeout") String timeout,
@PluginAttribute("maxActionsPerBulkRequest") Integer maxActionsPerBulkRequest,
@PluginAttribute("maxConcurrentBulkRequests") Integer maxConcurrentBulkRequests,
@PluginAttribute("maxVolumePerBulkRequest") String maxVolumePerBulkRequest,
@PluginAttribute("flushInterval") String flushInterval) {
if (cluster == null || cluster.isEmpty()) {
cluster = "elasticsearch";
}
if (host == null || host.isEmpty()) {
host = "localhost";
}
if (port == null || port == 0) {
port = 9300;
}
if (index == null || index.isEmpty()) {
index = "log4j2";
}
if (type == null || type.isEmpty()) {
type = "log4j2";
}
if (timeout == null || timeout.isEmpty()) {
timeout = "30s";
}
if (maxActionsPerBulkRequest == null) {
maxActionsPerBulkRequest = 1000;
}
if (maxConcurrentBulkRequests == null) {
maxConcurrentBulkRequests = 2 * Runtime.getRuntime().availableProcessors();
}
if (maxVolumePerBulkRequest == null || maxVolumePerBulkRequest.isEmpty()) {
maxVolumePerBulkRequest = "10m";
}
Settings settings = settingsBuilder()
.put("cluster.name", cluster)
.put("network.server", false)
.put("node.client", true)
.put("client.transport.sniff", true)
.put("client.transport.ping_timeout", timeout)
.put("client.transport.ignore_cluster_name", false)
.put("client.transport.nodes_sampler_interval", "30s")
.build();
TransportClient client = new TransportClient(settings, false);
client.addTransportAddress(new InetSocketTransportAddress(host, port));
if (client.connectedNodes().isEmpty()) {
logger.error("unable to connect to Elasticsearch cluster");
return null;
}
String description = "cluster=" + cluster + ",host=" + host + ",port=" + port + ",index=" + index + ",type=" + type;
ElasticsearchTransportClient elasticsearchTransportClient = new ElasticsearchTransportClient(client, index, type,
maxActionsPerBulkRequest, maxConcurrentBulkRequests,
ByteSizeValue.parseBytesSizeValue(maxVolumePerBulkRequest),
TimeValue.parseTimeValue(flushInterval, TimeValue.timeValueSeconds(30)));
ElasticsearchProvider elasticsearchProvider = new ElasticsearchProvider(elasticsearchTransportClient, description);
return elasticsearchProvider;
}
}